"""
性能管理器
优化Python-Java集成的性能表现
"""

import time
import threading
import psutil
import json
from pathlib import Path
from typing import Dict, Any, Optional, List
from dataclasses import dataclass, asdict
from collections import deque
import logging

@dataclass
class PerformanceMetrics:
    """性能指标"""
    request_id: str
    start_time: float
    end_time: Optional[float] = None
    processing_time: Optional[float] = None
    memory_usage_mb: float = 0.0
    cpu_percent: float = 0.0
    file_size_bytes: int = 0
    success: bool = True
    error_message: Optional[str] = None
    
    def finish(self, success: bool = True, error_message: Optional[str] = None):
        """完成性能记录"""
        self.end_time = time.time()
        self.processing_time = self.end_time - self.start_time
        self.success = success
        self.error_message = error_message

class PerformanceManager:
    """性能管理器"""
    
    def __init__(self, max_history: int = 1000):
        self.logger = logging.getLogger(__name__)
        self.max_history = max_history
        
        # 性能历史记录（线程安全）
        self._metrics_history: deque = deque(maxlen=max_history)
        self._current_metrics: Dict[str, PerformanceMetrics] = {}
        self._lock = threading.RLock()
        
        # 性能统计
        self._total_requests = 0
        self._success_requests = 0
        self._total_processing_time = 0.0
        
        # 系统监控
        self._system_monitor = SystemMonitor()
    
    def start_request_tracking(self, request_id: str) -> PerformanceMetrics:
        """开始跟踪请求性能"""
        with self._lock:
            metrics = PerformanceMetrics(
                request_id=request_id,
                start_time=time.time(),
                memory_usage_mb=self._get_memory_usage(),
                cpu_percent=self._get_cpu_usage()
            )
            
            self._current_metrics[request_id] = metrics
            self._total_requests += 1
            
            self.logger.debug(f"开始性能跟踪: {request_id}")
            return metrics
    
    def finish_request_tracking(self, request_id: str, success: bool = True, 
                               error_message: Optional[str] = None, 
                               output_file: Optional[Path] = None):
        """完成请求性能跟踪"""
        with self._lock:
            if request_id not in self._current_metrics:
                self.logger.warning(f"未找到性能跟踪记录: {request_id}")
                return
            
            metrics = self._current_metrics.pop(request_id)
            metrics.finish(success, error_message)
            
            # 记录文件大小
            if output_file and output_file.exists():
                metrics.file_size_bytes = output_file.stat().st_size
            
            # 更新统计
            if success:
                self._success_requests += 1
            self._total_processing_time += metrics.processing_time or 0
            
            # 添加到历史记录
            self._metrics_history.append(metrics)
            
            self.logger.info(f"完成性能跟踪: {request_id}, "
                           f"耗时: {metrics.processing_time:.2f}s, "
                           f"成功: {success}")
    
    def get_performance_summary(self) -> Dict[str, Any]:
        """获取性能摘要"""
        with self._lock:
            if self._total_requests == 0:
                return {"status": "no_data", "message": "暂无性能数据"}
            
            avg_processing_time = self._total_processing_time / self._total_requests
            success_rate = (self._success_requests / self._total_requests) * 100
            
            # 计算最近的性能指标
            recent_metrics = list(self._metrics_history)[-100:]  # 最近100个请求
            recent_avg_time = 0.0
            if recent_metrics:
                recent_times = [m.processing_time for m in recent_metrics if m.processing_time]
                recent_avg_time = sum(recent_times) / len(recent_times) if recent_times else 0
            
            return {
                "total_requests": self._total_requests,
                "success_requests": self._success_requests,
                "success_rate_percent": round(success_rate, 2),
                "avg_processing_time_seconds": round(avg_processing_time, 2),
                "recent_avg_processing_time_seconds": round(recent_avg_time, 2),
                "active_requests": len(self._current_metrics),
                "system_metrics": self._system_monitor.get_current_metrics()
            }
    
    def get_detailed_metrics(self, limit: int = 50) -> List[Dict[str, Any]]:
        """获取详细的性能指标"""
        with self._lock:
            recent_metrics = list(self._metrics_history)[-limit:]
            return [asdict(metric) for metric in recent_metrics]
    
    def detect_performance_issues(self) -> List[str]:
        """检测性能问题"""
        issues = []
        summary = self.get_performance_summary()
        
        # 检查成功率
        if summary.get("success_rate_percent", 100) < 90:
            issues.append(f"成功率偏低: {summary['success_rate_percent']}%")
        
        # 检查平均处理时间
        avg_time = summary.get("avg_processing_time_seconds", 0)
        if avg_time > 30:
            issues.append(f"平均处理时间过长: {avg_time}秒")
        
        # 检查系统资源
        system_metrics = summary.get("system_metrics", {})
        cpu_percent = system_metrics.get("cpu_percent", 0)
        memory_percent = system_metrics.get("memory_percent", 0)
        
        if cpu_percent > 80:
            issues.append(f"CPU使用率过高: {cpu_percent}%")
        
        if memory_percent > 85:
            issues.append(f"内存使用率过高: {memory_percent}%")
        
        # 检查磁盘空间
        disk_usage = system_metrics.get("disk_usage_percent", 0)
        if disk_usage > 90:
            issues.append(f"磁盘空间不足: {disk_usage}%已使用")
        
        return issues
    
    def optimize_recommendations(self) -> List[str]:
        """获取优化建议"""
        recommendations = []
        issues = self.detect_performance_issues()
        
        if "成功率偏低" in str(issues):
            recommendations.append("检查错误日志，修复常见失败原因")
            recommendations.append("实施更强的输入验证和错误处理")
        
        if "平均处理时间过长" in str(issues):
            recommendations.append("考虑使用Java守护进程模式减少启动开销")
            recommendations.append("优化大文件的流式处理")
            recommendations.append("增加超时配置的灵活性")
        
        if "CPU使用率过高" in str(issues):
            recommendations.append("实施请求队列和并发限制")
            recommendations.append("优化CPU密集型操作")
        
        if "内存使用率过高" in str(issues):
            recommendations.append("调整JVM堆内存参数")
            recommendations.append("实施内存缓存清理策略")
        
        if "磁盘空间不足" in str(issues):
            recommendations.append("清理临时文件和日志")
            recommendations.append("实施自动磁盘清理策略")
        
        return recommendations
    
    def _get_memory_usage(self) -> float:
        """获取当前内存使用量（MB）"""
        try:
            process = psutil.Process()
            return process.memory_info().rss / 1024 / 1024
        except:
            return 0.0
    
    def _get_cpu_usage(self) -> float:
        """获取当前CPU使用率"""
        try:
            return psutil.cpu_percent(interval=0.1)
        except:
            return 0.0
    
    def export_metrics(self, output_file: Path, format: str = "json"):
        """导出性能指标"""
        with self._lock:
            data = {
                "summary": self.get_performance_summary(),
                "detailed_metrics": self.get_detailed_metrics(limit=1000),
                "export_time": time.time()
            }
            
            if format.lower() == "json":
                with open(output_file, 'w', encoding='utf-8') as f:
                    json.dump(data, f, ensure_ascii=False, indent=2)
            
            self.logger.info(f"性能指标已导出到: {output_file}")

class SystemMonitor:
    """系统监控器"""
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
    
    def get_current_metrics(self) -> Dict[str, Any]:
        """获取当前系统指标"""
        try:
            # CPU指标
            cpu_percent = psutil.cpu_percent(interval=1)
            cpu_count = psutil.cpu_count()
            
            # 内存指标
            memory = psutil.virtual_memory()
            
            # 磁盘指标
            disk = psutil.disk_usage('/')
            
            # 进程指标
            process = psutil.Process()
            process_memory = process.memory_info()
            
            return {
                "cpu_percent": round(cpu_percent, 2),
                "cpu_count": cpu_count,
                "memory_total_gb": round(memory.total / 1024**3, 2),
                "memory_used_gb": round(memory.used / 1024**3, 2),
                "memory_percent": round(memory.percent, 2),
                "disk_total_gb": round(disk.total / 1024**3, 2),
                "disk_used_gb": round(disk.used / 1024**3, 2),
                "disk_usage_percent": round((disk.used / disk.total) * 100, 2),
                "process_memory_mb": round(process_memory.rss / 1024**2, 2),
                "process_cpu_percent": round(process.cpu_percent(), 2)
            }
        
        except Exception as e:
            self.logger.error(f"获取系统指标失败: {e}")
            return {"error": str(e)}

class PerformanceOptimizer:
    """性能优化器"""
    
    def __init__(self, performance_manager: PerformanceManager):
        self.performance_manager = performance_manager
        self.logger = logging.getLogger(__name__)
    
    def calculate_optimal_timeout(self, file_size_bytes: int, complexity_factor: float = 1.0) -> int:
        """
        根据文件大小和复杂度计算最优超时时间
        
        Args:
            file_size_bytes: 文件大小（字节）
            complexity_factor: 复杂度因子（1.0为标准，>1.0为复杂文档）
        """
        # 基础超时时间（秒）
        base_timeout = 60
        
        # 根据文件大小调整（每MB增加5秒）
        size_mb = file_size_bytes / 1024 / 1024
        size_timeout = size_mb * 5
        
        # 应用复杂度因子
        total_timeout = (base_timeout + size_timeout) * complexity_factor
        
        # 限制在合理范围内
        return max(60, min(int(total_timeout), 1800))  # 60秒到30分钟
    
    def suggest_java_memory_settings(self, max_file_size_mb: int = 100) -> Dict[str, str]:
        """建议Java内存设置"""
        # 基础内存配置
        heap_size = max(512, max_file_size_mb * 8)  # 文件大小的8倍作为堆内存
        
        return {
            "Xms": f"{heap_size//2}m",  # 初始堆内存
            "Xmx": f"{heap_size}m",     # 最大堆内存
            "XX:NewRatio": "3",         # 年轻代与老年代比例
            "XX:+UseG1GC": "",          # 使用G1垃圾收集器
            "XX:MaxGCPauseMillis": "200"  # 最大GC暂停时间
        }

# 全局性能管理器实例
_performance_manager = None

def get_performance_manager() -> PerformanceManager:
    """获取全局性能管理器实例"""
    global _performance_manager
    if _performance_manager is None:
        _performance_manager = PerformanceManager()
    return _performance_manager